package com.analysis.service;

import com.analysis.core.JarAnalyzer;
import com.analysis.model.AnalysisResponse;
import com.analysis.model.AnalysisResult;
import com.analysis.model.ClassDifference;
import com.analysis.util.JarVersionExtractor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.*;
import java.util.jar.JarFile;

@Slf4j
@Service
public class JarAnalysisService {

    @Autowired
    private JarAnalyzer jarAnalyzer;

    @Autowired
    private CacheService cacheService;

    public AnalysisResponse analyzeJars(MultipartFile oldJar, MultipartFile newJar) throws IOException {
        log.info("开始分析JAR包差异");
        log.info("旧版本JAR: {}", oldJar.getOriginalFilename());
        log.info("新版本JAR: {}", newJar.getOriginalFilename());

        AnalysisResponse response = new AnalysisResponse();
        
        Path tempDir = null;
        JarFile oldJarFile = null;
        JarFile newJarFile = null;
        
        try {
            // 创建临时目录
            tempDir = Files.createTempDirectory("jar-analysis-");
            
            // 保存上传的文件到临时目录
            Path oldJarPath = saveUploadedFile(oldJar, tempDir);
            Path newJarPath = saveUploadedFile(newJar, tempDir);

            // 打开JAR文件
            oldJarFile = new JarFile(oldJarPath.toFile());
            newJarFile = new JarFile(newJarPath.toFile());

            // 分析差异
            AnalysisResult result = jarAnalyzer.analyze(oldJarFile, newJarFile);

            // 设置版本信息
            response.setOldVersion(JarVersionExtractor.extractVersion(oldJarFile));
            response.setNewVersion(JarVersionExtractor.extractVersion(newJarFile));

            // 缓存结果
            String cacheKey = oldJar.getOriginalFilename() + ":" + newJar.getOriginalFilename();
            cacheService.cacheResult(cacheKey, result);

            // 设置响应
            response.setResult(result);
            response.setSuccess(true);
            
        } catch (Exception e) {
            log.error("分析过程出错", e);
            response.setSuccess(false);
            response.setError(e.getMessage());
        } finally {
            // 清理资源
            if (oldJarFile != null) {
                try {
                    oldJarFile.close();
                } catch (IOException e) {
                    log.warn("关闭旧版本JAR文件失败", e);
                }
            }
            if (newJarFile != null) {
                try {
                    newJarFile.close();
                } catch (IOException e) {
                    log.warn("关闭新版本JAR文件失败", e);
                }
            }
            if (tempDir != null) {
                try {
                    Files.walk(tempDir)
                        .sorted(Comparator.reverseOrder())
                        .map(Path::toFile)
                        .forEach(File::delete);
                } catch (IOException e) {
                    log.warn("清理临时文件失败", e);
                }
            }
        }
        
        return response;
    }

    private Path saveUploadedFile(MultipartFile file, Path directory) throws IOException {
        String originalFilename = file.getOriginalFilename();
        String filename = UUID.randomUUID().toString() + 
            (originalFilename != null ? originalFilename.substring(originalFilename.lastIndexOf('.')) : ".jar");
        
        Path targetPath = directory.resolve(filename);
        Files.copy(file.getInputStream(), targetPath);
        
        return targetPath;
    }

    private void deleteDirectory(File directory) {
        File[] files = directory.listFiles();
        if (files != null) {
            for (File file : files) {
                if (file.isDirectory()) {
                    deleteDirectory(file);
                } else {
                    if (!file.delete()) {
                        log.warn("无法删除文件: {}", file.getAbsolutePath());
                    }
                }
            }
        }
        if (!directory.delete()) {
            log.warn("无法删除目录: {}", directory.getAbsolutePath());
        }
    }
}
